package com.jbp.controller;

import java.io.*;
import java.lang.reflect.Array;
import java.time.Duration;
import java.util.*;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jbp.exception.RRException;
import com.jbp.redis.RedisConfigService;
import com.jbp.service.*;
import com.jbp.utils.*;
import com.jbp.utils.encryptUtils.AesEncryptUtil;
import com.jbp.utils.encryptUtils.RsaEncryptUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.StringBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import com.jbp.model.NoteMessage;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.jbp.utils.R.error;


/**
 *
 *
 * @author lucheng feng
 * @email jbp@gmail.com
 * @date 2020-06-14 22:21:26
 */
@Api(tags ="APP接口--发送验证码相关接口",hidden = true )
@ApiIgnore
@RestController
@RequestMapping("/notemessage")
public class NoteMessageController {
    @Autowired
    private NoteMessageService noteMessageService;

    @Autowired
    private RedisConfigService redisConfigService;

    @Autowired
    private SendNoteMessageFactory sendNoteMessageFactory;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AppConfigService appConfigService;

    @Autowired
    private PropertyService propertyService;

    @ApiOperation(value="发送验证码",notes="发送验证码")
    @ApiResponses({
            @ApiResponse(code = 200,message = "发送成功"),
            @ApiResponse(code = 201,message = "返回失败信息")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile",value = "账号",paramType = "query"),
    })
    @PostMapping("/send")
    /*public R send(@RequestBody NoteMessage noteMessage,HttpServletRequest request){
//        return R.error("敬请期待");
        if (StringUtils.isEmpty(noteMessage.getMobile())){
            return R.error("手机号不能为空");
        }
        String mobile = propertyService.decrypt(noteMessage.getMobile());
        noteMessage.setMobile(mobile);

        //暂时注释掉2025
        *//*if (!RegularExpressionUtil.checkMobile(noteMessage.getMobile())){
            return R.error("手机号格式不正确");
        }*//*
        String ip= IPReqUtil.getIp(request);
        Object obj=redisConfigService.get("ip:"+ip);
        if (obj != null){
            return error("发送验证码过于频繁，请稍后再试");
        }
        assertIp(ip);
//        String code=createRandomVcode();
        redisConfigService.set("ip:"+ip,ip,10L);
//        SendNoteMessageService sendNoteMessageService = sendNoteMessageFactory.getSendNoteMessageService();
////        boolean sendNoteMsgResult = sendNoteMessageService.send(noteMessage.getMobile(), code);
//
//        String note_temp = appConfigService.getVForCache("note_temp");

        String code = createRandomVcode();

        //https://push.spug.cc/send/Dw1GdmdQMGjl32qK
        String sdkappid = appConfigService.getV("message_flag");
//        String sdkappid = "Dw1GdmdQMGjl32qK";
        HashMap<String, Object> params = new HashMap<>();
        params.put("name", "短信验证码");
        params.put("code", code);
        params.put("targets", mobile);
        try {
//            long random = System.currentTimeMillis();
            String url = "https://push.spug.cc/send/"+sdkappid;//+"&contenttype=json";

            String json = HttpClient.doPostJson(params, null, url);
//            System.out.println("短信验证码="+json);
            if (StringUtils.isNotEmpty(json)) {
                JSONObject jsonObject = JSON.parseObject(json);
//                System.out.println("短信验证码为空返回结果="+jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


//        String code="666666";

//        boolean sendNoteMsgResult = LeXunTong.sendMsg("note_temp", noteMessage.getMobile(), code);
//        if(!sendNoteMsgResult) {
//            return error("发送失败");
//        }
        noteMessage.setCode(code);
        noteMessage.setIp(ip);
        noteMessage.setCreateTime(new Date());
        noteMessageService.save(noteMessage);
        redisConfigService.set(Constant.CODE_PREFIX+noteMessage.getMobile(),code,Constant.CODE_TIME);//验证码缓存时间 3分钟
        return R.ok().put("data",code);
        //     return R.ok();
    }*/

    public R send(@RequestBody NoteMessage noteMessage,HttpServletRequest request){
//        return R.error("敬请期待");
        if (StringUtils.isEmpty(noteMessage.getMobile())){
            return R.error("手机号不能为空");
        }
        String mobile = propertyService.decrypt(noteMessage.getMobile());
        noteMessage.setMobile(mobile);

        //暂时注释掉2025
        if (!RegularExpressionUtil.checkMobile(noteMessage.getMobile())){
            return R.error("手机号格式不正确");
        }
        String ip= IPReqUtil.getIp(request);
        Object obj=redisConfigService.get("ip:"+ip);
        if (obj != null){
            return error("发送验证码过于频繁，请稍后再试");
        }
        assertIp(ip);
        redisConfigService.set("ip:"+ip,ip,10L);
        String code = createRandomVcode();
        String APIKEY = "SMS01-00001-100793-5ykTABdyxej";//X-Api-Key
        String APISECRET = "1e23DK8ScF6wRP0ZD0B7Q29i0iCzwe41";
        Long timestamp = System.currentTimeMillis()/1000;//毫秒转化为秒
        String ran = UUIDUtil.inviteCode();
        String builds = APIKEY + APISECRET + timestamp + ran;
        String sign = SHA256Util.getSHA256(builds);
        if (null == sign){
            return error("发送验证码获取加密参数失败。");
        }
        HashMap<String, Object> headerMap = new HashMap<>();
        headerMap.put("X-Api-Key", APIKEY);
        headerMap.put("X-Timestamp", timestamp);
        headerMap.put("X-Nonce", ran);//每次请求的唯一标识，最长40个字符，不可重复（可用随机字符串）
        headerMap.put("X-Sign", sign.toLowerCase());

        Map<String, Object> data = new HashMap<>();
        data.put("template_id", 726);

        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> message = new HashMap<>();
        message.put("phone_number", mobile);

        Map<String, String> params = new HashMap<>();
        params.put("1", code);
        message.put("params", params);

        messages.add(message);
        data.put("messages", messages);

        try {
            String url = "https://api.feige.cn/sendsms/template/send";

            String json = HttpClient.doPostJson(data, headerMap, url);
//            System.out.println("短信验证码="+json);
            if (StringUtils.isNotEmpty(json)) {
                JSONObject jsonObject = JSON.parseObject(json);
//                System.out.println("短信验证码为空返回结果="+jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        noteMessage.setCode(code);
        noteMessage.setIp(ip);
        noteMessage.setCreateTime(new Date());
        noteMessageService.save(noteMessage);
        redisConfigService.set(Constant.CODE_PREFIX+noteMessage.getMobile(),code,Constant.CODE_TIME);//验证码缓存时间 3分钟
//        return R.ok().put("data",code);
        return R.ok().put("data","");
    }


    /**ip限制*/
    private void assertIp(String ip) {
//        ip = "171.43.250.208";
//        System.out.println(ip);
        if (!ipCheck(ip)) {
            throw new RRException("网络异常");
        }


        SetOperations setOperations = redisTemplate.opsForSet();
        String str =  ip.substring(0, ip.lastIndexOf("."));
        str = str.substring(0, str.lastIndexOf("."));

        //1. 限制国外ip 每10s只能发一条
        ValueOperations valueOperations = redisTemplate.opsForValue();
        if (!setOperations.isMember("whiteips:", str)) {
            Object iplock = valueOperations.get("whiteips:foreign:"+str);
            if (iplock!=null) {
                throw new RRException("请稍后再试—");
            } else {
                valueOperations.set("whiteips:foreign:"+str, 1,  Duration.ofSeconds(10));
            }
        }

        //2. 整体每秒只能发1条短信
        Object lock = valueOperations.get("whiteips:globle");
        if (lock!=null) {
            throw new RRException("请稍后再试。");
        } else {
            valueOperations.set("whiteips:globle", 1,  Duration.ofSeconds(1));
        }

        //3. 每个ip段每10s只能发一条
        Object iplock = valueOperations.get("whiteips:ip:"+str);
        if (iplock!=null) {
            throw new RRException("请稍后再试.");
        } else {
            valueOperations.set("whiteips:ip:"+str, 1,  Duration.ofSeconds(10));
        }
    }

    public static boolean ipCheck(String text) {
        if (text != null && !text.isEmpty()) {
            // 定义正则表达式
            String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." +"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
            // 判断ip地址是否与正则表达式匹配
            if (text.matches(regex)) {
                // 返回判断信息
                return true;
            } else {
                // 返回判断信息
                return false;
            }
        }
        return false;
    }

    public static String createRandomVcode() {
        //验证码
        String vcode = "";
        for (int i = 0; i < 6; i++) {
            vcode = vcode + (int) (Math.random() * 9);
        }
        return vcode;
    }

    public static void main(String[] args) {
        String mobile= "18627120716";
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRy6SBFrCyJf2j3V3sB7e1HpxVcpOqOiFIkfJJbfPweItjJ8ccNg3TIiN7dx2NGYfvl2eqzlJsjvN4f5uNuGP9a4hnUoLrCMxsuyoah8GahcjGruPUD4tyrOqoKqEHgzf917K3tHKXRuacW/BDRgp6r/JFcTxnomY9KYCV455R5wIDAQAB";
        String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJHLpIEWsLIl/aPdXewHt7UenFVyk6o6IUiR8klt8/B4i2Mnxxw2DdMiI3t3HY0Zh++XZ6rOUmyO83h/m424Y/1riGdSgusIzGy7KhqHwZqFyMau49QPi3Ks6qgqoQeDN/3Xsre0cpdG5pxb8ENGCnqv8kVxPGeiZj0pgJXjnlHnAgMBAAECgYEAhdTYYgLxGecTyFrI/4QqF2FNAobVk9oeeV43eT4sQZ513QRDmtrnn9rjlU9HWiGIjd9+suUH9kzWo9MHeHU9mpoJf6IuvJYje3+Ec/ydkBZGdsPJnzdMXtrEF5v2SQUGMDbdjH1c9JhPQf/JHXca1VF5ubzSWPkEkJmSYj4heGECQQDd11BQkpXojPgNyKyw/DNUZfc65c49Ti1igovuZNpmS1sOpvxSSxAZmazZcJfAWFBKRaICOKCBmqkmr++PNKrXAkEAqD617SzYW8SJP3Fa1p2WMKxIpCp4Y7Lm2abfFuCgNzjGzGiZnxxorFZZ+I41qOdec7iiKciQocyhgRbsjMw/cQJBAM3cUJt0a8gxiL7Byf8zCi73sETnnEsnkNYpbtD6pfDnXMhsDRoQrhATm2LsKOZFDbzegUiuY8PhUbak7RlnNmECQClWLxC04fu6EBacXTs5wLr4uWhMXwPv4rQ7Qbi3O+YVdxKl6IilTDp7hOOC3UBAiH5aMM2fT5nRUyUKYtg9HqECQGvSyX3qX1z/teNCjawKnfxeH9Xo0M32PmRi5hS80zBvRgQqgfyaocrlvvjiArVBtwne1Eycc4xWBtQAK5DTpTk=";
        String param = RsaEncryptUtil.encrypt(mobile, publicKey);
        System.out.println(param);
        String res = "kQtOegQMWhClwIQ4J58IGU/O9bzMfd1JxznU00fyS7tWkhU20xw72xf5WMIHziq1Gu6IDAcSmMfaCCL2TfgiWFKMJbystkq6Ox9nUskkRywOdNPLa90Y/1mKRrTRGiDZawPoMYugg+8IlBCbtLjSPrp4Pso38ErNZWpC9oGK6R4=";
        String decrypt = RsaEncryptUtil.decrypt(res, privateKey);
        System.out.println(decrypt);
    }
}
